#pragma once

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <cassert>
#include <cstdio>

#define POCELAIN_NAMESPACE pocelain
#define POCELAIN_NAMESPACE_BEGIN                                                                                       \
    namespace POCELAIN_NAMESPACE                                                                                       \
    {
#define POCELAIN_NAMESPACE_END }
#define POCELAIN_NAMESPACE_USING using namespace POCELAIN_NAMESPACE;
#ifndef POCELAIN_EXPORT
#define POCELAIN_EXPORT
#endif

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#define GL_GLEXT_PROTOTYPES
#include <GL/glut.h>
#endif

#include <cmath>
const double PI = std::atan(1.0) * 4;

#ifndef EM_PORT_API
#if defined(__EMSCRIPTEN__)
#define POCELAIN_EMSCRIPTEN
#include <emscripten.h>
#if defined(__cplusplus)
#define EM_PORT_API(rettype) extern "C" rettype EMSCRIPTEN_KEEPALIVE
#else
#define EM_PORT_API(rettype) rettype EMSCRIPTEN_KEEPALIVE
#endif
#else
#if defined(__cplusplus)
#define EM_PORT_API(rettype) extern "C" rettype
#else
#define EM_PORT_API(rettype) rettype
#endif
#endif
#endif

#define POCELAIN_LOG_DEBUG(...)                                                                                        \
    do                                                                                                                 \
    {                                                                                                                  \
        printf(__VA_ARGS__);                                                                                           \
        fflush(stdout);                                                                                                \
    } while (0)
#define POCELAIN_LOG_INFO(...)                                                                                         \
    do                                                                                                                 \
    {                                                                                                                  \
        printf(__VA_ARGS__);                                                                                           \
        fflush(stdout);                                                                                                \
    } while (0)
#define POCELAIN_LOG_WARN(...)                                                                                         \
    do                                                                                                                 \
    {                                                                                                                  \
        printf(__VA_ARGS__);                                                                                           \
        fflush(stdout);                                                                                                \
    } while (0)
#define POCELAIN_LOG_ERROR(...)                                                                                        \
    do                                                                                                                 \
    {                                                                                                                  \
        printf(__VA_ARGS__);                                                                                           \
        fflush(stdout);                                                                                                \
    } while (0)
#define POCELAIN_LOG_FATAL(...)                                                                                        \
    do                                                                                                                 \
    {                                                                                                                  \
        printf(__VA_ARGS__);                                                                                           \
        fflush(stdout);                                                                                                \
    } while (0)

#define POCELAIN_ASSERT(...) assert(__VA_ARGS__)
#define POCELAIN_STATIC_ASSERT(...) static_assert(__VA_ARGS__)

#ifdef POCELAIN_TEST
#define POCELAIN_LOG_TEST(...)                                                                                         \
    do                                                                                                                 \
    {                                                                                                                  \
        printf(__VA_ARGS__);                                                                                           \
        fflush(stdout);                                                                                                \
    } while (0)
#else
#define POCELAIN_LOG_TEST(...)
#endif
